/* -*- C++ -*- */

//=============================================================================
/*
 * @author Feloweria <380374483@qq.com>
 * Copyright (C) Feloweria
 * 
 * $ID 2013-06-26 05:22:03 PM
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @version 1.0
 */
//=============================================================================

#include "Thread/Thread.h"

FELOWRIA_BEGIN

void Wait(TimeValue value)
{
#ifdef __LINUX__
	timespec req = { 0, static_cast<int32>(value / FELOWRIA_TIME_ONE_NAO_SECOND) }, rem;
	nanosleep(&req, &rem);
#endif

#ifdef __WINDOWS__
	Sleep(static_cast<DWORD>(value / FELOWRIA_TIME_ONE_MILLI_SECOND));
#endif
}

bool Thread::ExcuteTask()
{
#ifdef __LINUX__
	pthread_attr_t attr;
	int32 result;
	
	{
		result = pthread_attr_init(&attr);
		
		if(result != 0)
		{
			if(result == ENOMEM)
				LOG_ERROR("Thread::Create \"pthread_attr_init\" A ENOMEM OCCUR");
			
			LOG_ERROR("Thread::Create \"pthread_attr_init\" LOG_ERROR");
			return false;
		}
	}
	
	{
		result = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
		
		if(result != 0)
		{
			if(result == EINVAL)
				LOG_ERROR("Thread::Create \"pthread_attr_setdetachstate\" An invalid value was specified in state which must be THREAD_DETACH or THREAD_JOINABLE");
			
			LOG_ERROR("Thread::Create \"pthread_attr_setdetachstate\" LOG_ERROR");
			pthread_attr_destroy(&attr);
			return false;
		}
	}


	pthread_create(&tid,&attr,
	[](void *object) -> void*
	{
		Thread *thread = (Thread*) object;
		
		while(thread->Excute())
			;

		LOG_TRACE("Thread Run");
		return thread;
	}
	,this);
	
	pthread_attr_destroy(&attr);
#endif

#ifdef __WINDOWS__
	CreateThread(NULL, 0, [](void *object) -> DWORD
	{
		Thread *thread = (Thread*)object;

		while (thread->Excute())
			;

		LOG_TRACE("Thread End");
		return 1;
	}, this, 0, &tid);
#endif
	return true;
}


FELOWRIA_END
